﻿using XfTechOAWeb.Data;
using XfTechOAWeb.IService;
using XfTechOAWeb.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.SqlClient;
using Newtonsoft.Json;  //序列化
using System.Threading.Tasks;
using XfTechOAWeb.Infrastructure.RedisCache;
using AutoMapper;
using MD5Hash;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using XfTechOAWeb.Data.Base;
using Microsoft.EntityFrameworkCore;
using XfTechOAWeb.Dtos;

namespace XfTechOAWeb.Service
{
    /// <summary>
    /// 用户模块 应用服务实现类
    /// </summary>
    public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IRepository<UserRole> _userRoleRepository;
        private readonly IRepository<Permission> _permissionRepository;
        private readonly IRepository<RolePermission> _rolePermissionRepository;
        private readonly IRepository<Role> _roleRepository;
        private readonly ICSRedisHelper _redisClient;
        private readonly IMapper _mapper;   //注入Automapper接口
        private readonly IHttpContextAccessor _httpContextAccessor;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userRepository"></param>
        /// <param name="redisClient"></param>
        /// <param name="mapper"></param>
        /// <param name="userRoleRepository"></param>
        /// <param name="roleRepository"></param>
        public UserService(IUserRepository userRepository,
            ICSRedisHelper redisClient,
            IMapper mapper,
            IRepository<UserRole> userRoleRepository,
            IRepository<Role> roleRepository,
            IHttpContextAccessor httpContextAccessor,
            IRepository<Permission> permissionRepository,
            IRepository<RolePermission> rolePermissionRepository)
        {
            _userRepository = userRepository;
            _redisClient = redisClient;
            _mapper = mapper;
            _userRoleRepository = userRoleRepository;
            _roleRepository = roleRepository;
            _httpContextAccessor = httpContextAccessor;
            _permissionRepository = permissionRepository;
            _rolePermissionRepository = rolePermissionRepository;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public UserDto GetUserByNameAndPwd(UserLoginRequestDto input)
        {
            try
            {
                UserDto result = null;
                //获取Md5字符串
                string pwdMd5 = input.Password.GetMD5();
                User user = _userRepository.Table.Where(x => x.Account.Equals(input.Name) && x.Password.Equals(pwdMd5) && x.IsDeleted == false && x.Status == true).SingleOrDefault();

                if (user != null)
                {
                    //result = new UserDto
                    //{
                    //    Account = user.Account,
                    //    Status = user.Status,
                    //    UId = user.UId,
                    //    UName = user.UName
                    //};
                    result = _mapper.Map<UserDto>(user); //使用AutoMapper进行对象间映射，“偷懒”
                }
                return result;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public int Add(UserAddDto user)
        {
            user.Password = user.Password.GetMD5();
            List<User> users = _userRepository.Table.ToList();
            int number = users.Where(x => x.Account.Contains(user.Account)).Count();
            if (number > 0)
            {
                return 0;
            }
            else
            {
                User user1 = new User();
                user1.Account = user.Account;
                user1.Password = user.Password;
                user1.UName = user.UName;
                user1.Status = user.Status;
                user1.IsDeleted = user.IsDeleted;
                user1.CreatedUserID = Convert.ToInt32(_httpContextAccessor.HttpContext.User.FindFirst(x => x.Type == ClaimTypes.NameIdentifier).Value ?? "0");
                _userRepository.Insert(user1);
                return _userRepository.SaveChanges();
            }

        }

        /// <summary>
        /// 批量逻辑删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public int Del(string ids)
        {
            string[] arrId = ids.Split(',');
            var list = _userRepository.Table.Where(x => arrId.Contains(x.UId.ToString())).ToList();
            list.ForEach(item =>
            {
                item.IsDeleted = true;
            });

            return _userRepository.SaveChanges();
        }

        /// <summary>
        /// 分页显示用户信息
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public PageResponseModel<UserDto> GetList(UserPageRequestDto input)
        {
            var query = from s in _userRepository.Table   //查用户表
                        where (string.IsNullOrEmpty(input.Name) || s.UName.Contains(input.Name)) //用户表查询条件
                        where (string.IsNullOrEmpty(input.DepId.ToString()) || s.DepId.Contains(input.DepId.ToString()))
                        where (string.IsNullOrEmpty(input.Status.ToString()) || s.Status == input.Status)
                        where (s.IsDeleted == false)
                        orderby s.UId
                        select new UserDto
                        {
                            UId = s.UId,
                            Account = s.Account,
                            Status = s.Status,
                            UName = s.UName,
                            CreatedTime = s.CreatedTime,
                            Roles = string.Join(',', (from ur in _userRoleRepository.Table //角色用户表
                                                      join r in _roleRepository.Table      //角色表   两表联查
                                                      on ur.RoleId equals r.RId
                                                      where ur.UserId == s.UId
                                                      select r.RName).ToArray())
                        };

            PageResponseModel<UserDto> page = new PageResponseModel<UserDto>()
            {
                TotalCount = query.Count(),
                PageList = query.Skip((input.PageIndex - 1) * input.PageSize)
                                .Take(input.PageSize)
                                .ToList()

            };

            return page;
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public int Upt(UserUptDto user)
        {
            if (!string.IsNullOrEmpty(user.Password))
            {
                user.Password = user.Password.GetMD5();
                User users = _userRepository.Table.Where(x => x.UId == user.Uid).SingleOrDefault();
                if (user.Password.Contains(users.Password))
                {
                    return 0;
                }
                users.Password = user.Password;
                users.UName = user.UName;
                users.Status = user.Status;
                int data = _userRepository.SaveChanges();
                return data;
            }
            else
            {
                User users = _userRepository.Table.Where(x => x.UId == user.Uid).SingleOrDefault();
                users.UName = user.UName;
                users.Status = user.Status;
                int data = _userRepository.SaveChanges();
                return data;
            }

        }

        /// <summary>
        /// 给用户添加角色
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="rid"></param>
        /// <returns></returns>
        public int AddUserRole(UserRoleAddDto urole)
        {
            return _userRepository.AddUserRole(urole.uid, urole.rid);
        }


        /// <summary>
        /// 获取用户权限
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<Permission> GetUserPermissions(int userId)
        {
            //查询用户所对应的角色Id
            List<int> roleIds = _userRoleRepository.Table.Where(x=>x.UserId== userId).Select(x=>x.RoleId).ToList();

            //查询用户的所有权限信息
            var query = from per in _permissionRepository.Table
                        join rolePer in (
                            from rp in _rolePermissionRepository.Table
                                where roleIds.Contains(rp.RoleId)
                            select rp
                            ) on per.PId equals rolePer.PermissionId
                        select per;

            return query.ToList();
        }


        /// <summary>
        /// 获取用户菜单
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<PermissionTreeDto> GetUserMenu(int userId)
        {
            var data = _userRepository.LoadUserMenu(userId);

            //序列化反序列化
            string json = JsonConvert.SerializeObject(data);
            List<Permission> permissions = JsonConvert.DeserializeObject<List<Permission>>(json);

            return GetMenuTree(permissions, 0);
        }

        //递归方法 拼接 树
        private List<PermissionTreeDto> GetMenuTree(List<Permission> permissions, int pid)
        {
            //查询父Id下面的所有数据
            var list = permissions.Where(x => x.ParentId == pid).ToList();
            if (list.Count == 0)
                return null;

            List<PermissionTreeDto> tos = new List<PermissionTreeDto>();
            list.ForEach(x =>
            {
                var node = new PermissionTreeDto()
                {
                    PId = x.PId,
                    PTitle = x.PTitle,
                    ParentId = x.ParentId,
                    PAction = x.PAction,
                    IconName = x.IconName,
                    IsMenu = x.IsMenu,
                    PApiUrl = x.PApiUrl,
                    SortNo = x.SortNo,
                    Children = GetMenuTree(permissions, x.PId)
                };

                tos.Add(node);
            });

            return tos;
        }

        /// <summary>
        /// 获取用户数量并缓存到redis中
        /// </summary>
        /// <returns></returns>
        public void GetUserCount()
        {
            int userCount = _userRepository.Table.Count(); //返回所有的用户数
            _redisClient.Set("UserTotalCount", userCount); //保存到Redis中
        }

        /// <summary>
        /// 根据主键获取用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public User Get(int id)
        {
            return _userRepository.GetById(id);
        }
        /// <summary>
        /// 用户修改密码
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public int PasswordUpt(UserPassUpt password)
        {
            User user = _userRepository.Table.Where(x => x.UId == password.Uid).SingleOrDefault();
            password.Password = password.Password.GetMD5();
            user.Password = password.Password;
            return _userRepository.SaveChanges();
        }
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public User UserGet(int userid)
        {
            return _userRepository.GetById(userid);
        }
    }
}
